package server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import frame.Frame;

public class AlertsServer extends Thread {
	
	public static final int PORT_HIGH_PRIO = 5190;
	
	public static final int LOW_POOL_CORE_SIZE = 400;
	public static final int LOW_POOL_MAX_SIZE = 400;
	public static final int LOW_POOL_QUEUE_SIZE = 300;
	
	public static final int KEEP_ALIVE_TIME = 4000;
	
	protected boolean active = true;
	
	protected boolean sleeping = false;
	
	private BlockingQueue<Runnable> queue;
	private ThreadPoolExecutor executor;
	
	public BlockingQueue<Frame> persistentQueue;
	
	protected DatagramSocket dataSocket;
	
	private SimpleDateFormat sdf;
	
	public AlertsServer() throws IOException{
		
		queue = new ArrayBlockingQueue<Runnable>(LOW_POOL_QUEUE_SIZE, true);
		executor = new ThreadPoolExecutor(LOW_POOL_CORE_SIZE, LOW_POOL_MAX_SIZE, 
				KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, queue);
		
		dataSocket = new DatagramSocket(PORT_HIGH_PRIO);
		
		sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
	}
	
	public void run(){
		
		while(active){
			
			try {
				synchronized(this){
					while(sleeping){
						wait();
					} 
				}
				
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}

			try {
				byte[] bufIn = new byte[128];
				
				DatagramPacket packet = new DatagramPacket(bufIn, bufIn.length);
				dataSocket.receive(packet);
				
				System.out.println("Trama recibida en Puerto High " + sdf.format(new Date()));
				
				Task t = new Task(bufIn, persistentQueue);
				
				executor.execute(t);
			} 
			catch (IOException e) {
				e.printStackTrace();
			}

		}
	}
	
	public void setPersistentQueue(BlockingQueue<Frame> persistentQueue){
		this.persistentQueue = persistentQueue;
	}
	
	public void suspendServer(){
		sleeping = true;
		System.out.println("Alerts Server 2 suspending...");
	}
	
	public synchronized void resumeServer(){
		sleeping = false;
		notify();
		System.out.println("Alerts Server 2 resuming...");
	}

}
